package com.netmarch.jt809.server;

import cn.hutool.json.JSONUtil;
import com.netmarch.jt809.bean.Message;
import com.netmarch.jt809.server.bean.Container;
import com.netmarch.jt809.server.bean.Gps;
import cn.hutool.http.HttpUtil;
import io.searchbox.client.JestClient;
import io.searchbox.client.JestClientFactory;
import io.searchbox.client.config.HttpClientConfig;
import io.searchbox.core.Index;
import org.apache.commons.lang3.time.FastDateFormat;
import org.jboss.netty.buffer.ChannelBuffer;
import org.jboss.netty.buffer.ChannelBuffers;
import org.jboss.netty.channel.ChannelFuture;
import org.jboss.netty.channel.ChannelHandlerContext;
import org.jboss.netty.channel.MessageEvent;
import org.jboss.netty.channel.SimpleChannelHandler;

import java.io.IOException;
import java.io.UnsupportedEncodingException;
import java.math.BigDecimal;
import java.nio.ByteBuffer;
import java.nio.ByteOrder;
import java.nio.charset.Charset;
import java.text.ParseException;
import java.util.Date;
import java.util.List;
import java.util.Map;

public class BusiHandler extends SimpleChannelHandler {

    private static FastDateFormat fdfDay=FastDateFormat.getInstance("yyyy-MM-dd HH:mm:ss");
    @Override
    public void messageReceived(ChannelHandlerContext ctx, MessageEvent e) throws Exception {
        // TODO Auto-generated method stub
        Message msg = (Message) e.getMessage();
        switch (msg.getMsgId()) {
            case 0x1001:
                System.out.println("登陆。");
                login(msg, ctx, e);
                break;
            case 0x1005:
                System.out.println("主链路连接保持请求消息。");
                heartBeat(msg, ctx, e);
                break;
            case 0x1200:
                System.out.println("主链路动态信息交换消息");
                System.out.println("msg:" + msg.toString());
                parseGPS(msg, ctx, e);
                break;
            default:
                break;
        }
    }

    private void login(Message msg, ChannelHandlerContext ctx, MessageEvent e) {
        int userId = msg.getMsgBody().readInt();
        String passWord = msg.getMsgBody().readBytes(8).toString(Charset.forName("GBK"));
        String ip = msg.getMsgBody().readBytes(32).toString(Charset.forName("GBK"));
        int port = msg.getMsgBody().readUnsignedShort();
        msg.getMsgBody().clear();
       /* System.out.println("userId:" + userId);
        System.out.println("passWord:" + passWord);
        System.out.println("ip:" + ip);
        System.out.println("port:" + port);
        System.out.println("login-----------------");*/
        Message msgRep = new Message(0x1002);
        ChannelBuffer buffer = ChannelBuffers.buffer(5);
        buffer.writeByte(0x00);
        //校验码，临时写死
        buffer.writeInt(1221);
        msgRep.setMsgBody(buffer);
        ChannelFuture f = e.getChannel().write(msgRep);
        System.out.println(msgRep.toString());
//        try {
////            LogUtil.createLogFile(userId + "," + passWord + "," + ip
////                    + "," + port + "," + new SimpleDateFormat("yyyy-MM-dd HH:mm:ss").format(new Date()) +
////                    "," + msgRep.toString(), "login");
//            System.out.println(userId + "," + passWord + "," + ip
//                    + "," + port + "," + new SimpleDateFormat("yyyy-MM-dd HH:mm:ss").format(new Date()) +
//                    "," + msgRep.toString());
//        } catch (Exception e1) {
//            e1.printStackTrace();
//            System.err.println("log-fail");
//        }
        //f.addListener(ChannelFutureListener.CLOSE);
    }

    private void heartBeat(Message msg, ChannelHandlerContext ctx, MessageEvent e) {
        Message msgRep = new Message(0x1006);
        ChannelBuffer buffer = ChannelBuffers.buffer(0);

        msgRep.setMsgBody(buffer);
        ChannelFuture f = e.getChannel().write(msgRep);
    }

    private void parseGPS(Message msg, ChannelHandlerContext ctx, MessageEvent e) throws UnsupportedEncodingException {

        List<byte[]> list = msg.getContentList();
        for (byte[] bean : list) {
            handleArray(bean);
        }

    }

    public void handleArray(byte[] bean) throws UnsupportedEncodingException {
        if (bean[0] != (0x5b)) return;
        byte[] arr = new byte[]{bean[23], bean[24], bean[25], bean[26], bean[27], bean[28], bean[29], bean[30], bean[31], bean[32], bean[33], bean[34], bean[35], bean[36], bean[37], bean[38], bean[39], bean[40], bean[41], bean[42], bean[43]};
        String carNum = new String(arr, "GBK").substring(0, 7);

        byte carColor = bean[44];

        arr = new byte[]{bean[45], bean[46]};
        int dataType = ByteBuffer.wrap(arr).order(ByteOrder.BIG_ENDIAN).getShort();

        arr = new byte[]{bean[47], bean[48], bean[49], bean[50]};
        int capacity = bytesToInt(arr);

        byte encryptKey = bean[51];
        byte day = bean[52];
        byte month = bean[53];

        arr = new byte[]{bean[54], bean[55]};
        int year = ByteBuffer.wrap(arr).order(ByteOrder.BIG_ENDIAN).getShort();

        byte hour = bean[56];
        byte minute = bean[57];
        byte second = bean[58];

        arr = new byte[]{bean[59], bean[60], bean[61], bean[62]};
        int lon = bytesToInt(arr);

        arr = new byte[]{bean[63], bean[64], bean[65], bean[66]};
        int lat = bytesToInt(arr);
        /*System.out.println("carNum:" + carNum + "\n" +
                "carColor:" + carColor + "\n" +
                "dataType:" + dataType + "\n" +
                "capacity:" + capacity + "\n" +
                "encryptKey:" + encryptKey + "\n" +
                "day:" + day + "\n" +
                "month:" + month + "\n" +
                "year:" + year + "\n" +
                "hour:" + hour + "\n" +
                "minute:" + minute + "\n" +
                "second:" + second + "\n" +
                "lon:" + lon + "\n" +
                "lat:" + lat);*/
        JestClient jestClient = null;
        try {
//            LogUtil.createLogFile(carNum + "," + carColor + "," + dataType
//                    + "," + capacity + "," + encryptKey
//                    + "," + day + "," + month
//                    + "," + year + "," + hour
//                    + "," + minute + "," + second
//                    + "," + lon + "," + lat, "data");

//            LogUtil.createSQL("insert into carinfoskt (carnum,carcolor,datatype,capacity," +
//                    "encryptkey,day,month,year,hour,minute,second,lon,lat) values ('" + carNum + "','" + carColor + "','" + dataType
//                    + "','" + capacity + "','" + encryptKey
//                    + "','" + day + "','" + month
//                    + "','" + year + "','" + hour
//                    + "','" + minute + "','" + second
//                    + "','" + lon + "','" + lat + "');");
            JestClientFactory factory = new JestClientFactory();
            factory.setHttpClientConfig(new HttpClientConfig.Builder("http://127.0.0.1:9200").connTimeout(60000).readTimeout(60000).multiThreaded(true).build());
            jestClient = factory.getObject();
            Gps gps = new Gps();
            gps.setTime(fdfDay.parse(year+"-"+month+"-"+day+" "+hour+":"+minute+":"+second));
            gps.setCarNum(carNum);
            gps.setCarColor(Integer.parseInt(carColor+""));
            gps.setDataType(Integer.parseInt(dataType+""));
            gps.setCapacity(Integer.parseInt(capacity+""));
            gps.setEncryptKey(Integer.parseInt(encryptKey+""));
            gps.setLat(new BigDecimal(lat).divide(new BigDecimal(1000000)));
            gps.setLon(new BigDecimal(lon).divide(new BigDecimal(1000000)));
            Index index = new Index.Builder(gps).index("gps").type("position").build();
            jestClient.execute(index);
            //将gps转换为高德坐标系再存入新的es文档库下
            String url = "https://restapi.amap.com/v3/assistant/coordinate/convert?locations="+gps.getLon()+","+gps.getLat()+"&coordsys=gps&output=json&key=51139266baf57dd5b14c184d8a09a2b5";
            String result1= HttpUtil.get(url);
            Map map = JSONUtil.toBean(result1,Map.class);
            if(map.get("locations") != null){
                String d[] = map.get("locations").toString().split(",");
                gps.setLon(new BigDecimal(d[0]));
                gps.setLat(new BigDecimal(d[1]));
                Index index2 = new Index.Builder(gps).index("gdgps").type("position").build();
                jestClient.execute(index2);
            }
            jestClient.close();
        } catch (IOException e1) {
            e1.printStackTrace();
            System.err.println("log-fail");
        } catch (ParseException e) {
            e.printStackTrace();
        }
    }

    public static Container skipIF(int start, int num, ChannelBuffer buffer) {
        Container container = new Container();
        byte[] byteHex = new byte[num];
        int startpoint = start;
        for (int i = 0; i < num; i++) {
            if (buffer.getByte(start) == 0x5a || buffer.getByte(start) == 0x5e) {
                buffer.skipBytes(1);//1 byte
                start++;
            }
            start++;
        }

        int temp = 0;
        for (int i = startpoint; i < start; i++) {
            if (buffer.getByte(i) == 0x5a && buffer.getByte(i + 1) == 0x01) {
                byteHex[temp++] = 0x5b;
                i++;
            } else if (buffer.getByte(i) == 0x5a && buffer.getByte(i + 1) == 0x02) {
                byteHex[temp++] = 0x5a;
                i++;
            } else if (buffer.getByte(i) == 0x5e && buffer.getByte(i + 1) == 0x01) {
                byteHex[temp++] = 0x5d;
                i++;
            } else if (buffer.getByte(i) == 0x5e && buffer.getByte(i + 1) == 0x02) {
                byteHex[temp++] = 0x5e;
                i++;
            } else {
                byteHex[temp++] = buffer.getByte(i);
            }
            //System.out.print(byteHex[temp - 1] + "，");
        }
        //System.out.println();
        container.setStart(start);
        container.setHex(byteHex);
        return container;
    }

    public static int bytesToInt(byte[] src) {
        int value;
        value = (int) (((src[0] & 0xFF) << 24)
                | ((src[0 + 1] & 0xFF) << 16)
                | ((src[0 + 2] & 0xFF) << 8)
                | (src[0 + 3] & 0xFF));
        return value;
    }

    public static void main(String[] args) {
        JestClient jestClient = null;
        JestClientFactory factory = new JestClientFactory();
        factory.setHttpClientConfig(new HttpClientConfig.Builder("http://127.0.0.1:9200").connTimeout(60000).readTimeout(60000).multiThreaded(true).build());
        jestClient = factory.getObject();
        for(int i = 6449;i<100000;i++){
            try {
//                BusiHandler  myExecutor = new BusiHandler();
//                myExecutor.fun(i);
//                System.out.println("你先睡着,我先回家啦~");
//                Thread.sleep(1000); //1000 毫秒，也就是1秒.
//                JestClient jestClient = null;
                Gps gps = new Gps();
                gps.setId(i);
                gps.setTime(new Date());
                gps.setCarNum("苏U88822");
                gps.setCarColor(Integer.parseInt(1+""));
                gps.setDataType(Integer.parseInt(2+""));
                gps.setCapacity(Integer.parseInt(3+""));
                gps.setEncryptKey(Integer.parseInt(4+""));
                gps.setLat(new BigDecimal(31413732+i+1).divide(new BigDecimal(1000000)));
                gps.setLon(new BigDecimal(120981920+i+1).divide(new BigDecimal(1000000)));
                Index index = new Index.Builder(gps).index("gps").type("position").build();
                jestClient.execute(index);
//                jestClient.close();
            } catch (Exception e) {
                e.printStackTrace();
            }
        }
    }

//        private ExecutorService executor = Executors.newCachedThreadPool() ;
//        public void fun(int i) throws Exception {
//          executor.submit(new Runnable(){
//          @Override
//          public void run() {
//              try {
//                  //要执行的业务代码，我们这里没有写方法，可以让线程休息几秒进行测试
////                  Thread.sleep(10000);
//                  System.out.println("睡够啦-----"+i);
//              }catch(Exception e) {
//                  throw new RuntimeException("报错啦！！");
//              }
//          }
//        });
//      }
}
